package net.roostertech.bta2dpfixer;

import java.util.List;

import android.app.Service;
import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothClass;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfile.ServiceListener;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;

public class BTFixerService extends Service {
	
	public static final String DEVICE_CONNECTED = "DEVICE_CONNECTED";
	BluetoothA2dp mBtA2dp;
	BluetoothAdapter mBtAdpt;
	
	ServiceListener mSListerner;
	private final String LOGTAG = "BTFixerService";

	DeviceDAO mDao;
	BluetoothDevice mBtDev;
	Handler mHandler;
	final int WAIT_TIME_MS = 10000;
	final int CYCLING_TIME_MS = 5000;
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		super.onCreate();
		
		mSListerner = new ServiceListener() {
			@Override
			public void onServiceDisconnected(int arg0) {
			}
			
			@Override
			public void onServiceConnected(int arg0, BluetoothProfile a2dpProfile) {
				mBtA2dp = (BluetoothA2dp) a2dpProfile;
				
				Log.i(LOGTAG, "Connected to A2DP ");
			}
		};
		
		BluetoothAdapter.getDefaultAdapter()
		  .getProfileProxy(getApplicationContext(), mSListerner,  BluetoothProfile.A2DP);
		Log.i(LOGTAG, "Created Service");
		
		mDao = DeviceDAO.getInstance(getApplicationContext());
		mBtAdpt = BluetoothAdapter.getDefaultAdapter();
		mHandler = new Handler();
	}
	
	public String getServiceClasses(BluetoothClass c) {
		StringBuilder sb = new StringBuilder();
		if (c.hasService(BluetoothClass.Service.AUDIO)) {
			sb.append("AUDIO ");
		}
		if (c.hasService(BluetoothClass.Service.CAPTURE)) {
			sb.append("CAPTURE ");
		}
		if (c.hasService(BluetoothClass.Service.INFORMATION)) {
			sb.append("INFORMATION ");
		}
		if (c.hasService(BluetoothClass.Service.LIMITED_DISCOVERABILITY)) {
			sb.append("LIMITED_DISCOVERABILITY ");
		}
		if (c.hasService(BluetoothClass.Service.NETWORKING)) {
			sb.append("NETWORKING ");
		}
		if (c.hasService(BluetoothClass.Service.OBJECT_TRANSFER)) {
			sb.append("OBJECT_TRANSFER ");
		}
		if (c.hasService(BluetoothClass.Service.POSITIONING)) {
			sb.append("POSITIONING ");
		}
		if (c.hasService(BluetoothClass.Service.RENDER)) {
			sb.append("RENDER ");
		}
		if (c.hasService(BluetoothClass.Service.TELEPHONY)) {
			sb.append("TELEPHONY ");
		}
		
		return sb.toString();
	}
	@Override
	public void onStart(Intent intent, int startId) {
		super.onStart(intent, startId);
	}

	boolean checkA2dpProfile(BluetoothDevice device) {
		List<BluetoothDevice> a2dpDevices = mBtA2dp.getConnectedDevices();
		
		for (BluetoothDevice ad : a2dpDevices) {
			if (ad.getAddress().equals(device.getAddress())) {
				return true;
			}
		}
		return false;
	}
	
	
	Runnable enableBt = new Runnable() {
		
		@Override
		public void run() {
			mBtAdpt.enable();
		}
	};
	
	Runnable checkA2dp = new Runnable() {
		@Override
		public void run() {
			if (checkA2dpProfile(mBtDev)) {
				Log.i(LOGTAG, "Have A2DP, good to go");
			} else {
				Log.i(LOGTAG, "Still no A2DP, need to restart");
				mBtAdpt.disable();
				mHandler.postDelayed(enableBt, CYCLING_TIME_MS);
			}
		}
	};
	
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		super.onStartCommand(intent, flags, startId);
		
		if (intent != null && intent.getAction().equals(DEVICE_CONNECTED)) {
			BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
			
			BluetoothClass devClass = device.getBluetoothClass();
			Log.i(LOGTAG, "Connected Device " + device.getName() + " class "+ devClass.getDeviceClass() + " major " + devClass.getMajorDeviceClass());
			Log.i(LOGTAG, getServiceClasses(devClass));			

			if (!mDao.isA2DP(device.getName())) {
				Log.i(LOGTAG, "Not marked - ignoring ");
				return START_NOT_STICKY;
			}
			if (checkA2dpProfile(device)) {
				Log.i(LOGTAG, "Have A2DP, good to go");
			} else {
				Log.i(LOGTAG, "Device does not have A2DP yet, recheck in " + WAIT_TIME_MS);
				mBtDev = device;
				new Handler().postDelayed(checkA2dp, WAIT_TIME_MS);
			}
		}
		return  START_STICKY;
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		DeviceDAO.getInstance(getApplicationContext()).close();
	}

}
